file strlist.txt Copyright (C) 1995, 1996 by John Montbriand. All Rights Reserved. ABOUT STRLIST... Copyright (C) 1995, 1996 by John Montbriand. All Rights Reserved. Distribute freely in areas where the laws of copyright apply. Use at your own risk. Do not distribute modified copies. These various string list libraries are for free! ABOUT THE AUTHOR... Comments, questions, or suggestions are always welcome. John Montbriand tinyjohn@sasknet.sk.ca P.O. Box. 1133 Saskatoon Saskatchewan Canada S7K 3N2 WHY IS IT FOR FREE? none of your business, but if you have some business for me, I'll see what I can do.. OUTLINE OF TOPICS STRING LISTS, WHAT ARE THEY? IMPLEMENTATION NOTES MATERIALS LEGAL STUFF FURTHER REFERENCE SERVICES PROVIDED (OVERVIEW) BE CAREFUL (CAVEATS) COMPARISONS AND ORDERING OVERVIEW OF ROUTINES SPECIFIC ROUTINE DESCRIPTIONS STRING LISTS, WHAT ARE THEY? Strings are commonly used to store textual information for retrieval and display for human interpretation. On the macintosh, the STR# resource type has been around since the beginning of mactime and in itself it can be particularily useful when dealing with strings and groups of strings, while at the same time it is an ecconomical way to store strings in memory and on disk. String lists are a storage efficient way to store the string type data. IMPLEMENTATION NOTES String lists are stored as A two byte integer value containing the number of strings that follow. Each string is stored consecutively end to end as a length byte followed by the data bytes making up the string. Elements in string lists are indexed as 1, 2, ..., n and all of the routines defined herein use this convention. As string lists are stored in handles, there are other non-obvious issues involved here. Most notably, some of the routines herein return pointers to strings stored inside of string lists (which are stored in side of handles). Handles can be moved by other routines that call the memory manager and as such, this behavior could invalidate such a string pointer unless the string list handle is locked. THE RULE: when you use the routine StringListElt to retrieve strings from string lists, use HLock to lock the string list. MATERIALS The STR# format itself is the copyright property of Apple computer and has been known to the public since 1983. The routines documented herein are the copyright property of John Montbriand. I am making these routines available to the macintosh programming community because I feel it's about time someone did! I hope all who find them, use them well. Compiled and tested with MPW C, MW C, Symantic C, and MPW PPC. LEGAL STUFF These libraries are provided for free and you may use them in any program you make; however, if you're particular about having signed documentation that proves this fact in your posession then, as I would like to ensure these libraries are widely used, I would be glad provide such documents for you. I don't think this is entirly necessary, but I can understand that some folks feel quite strongly about such issues and prefer to do things in writing. If you would like for me to send you a signed document saying that you have license to use these routines in your programs, then send me a couple of bucks to cover postage and handling and I'll send you back a signed letter saying you have license to use these routines in any software you make. I think two or three dollars is fair as I don't really get a big thrill out of printing stuff out and mailing it, and that's usually enough to cover postage to anywhere in the world. I s'pose you'd have to figure out how much it would cost for me to mail a letter to you from here in Canada. FURTHER REFERENCE strlist.h and strlist.c contain routines for accessing the string list data type. You can use these routines to access or modify information stored in any STR# resource. As well, you can use these routines for creating and manipulating lists of strings in memory. The following sources describe what is involved here in more detail: Inside Macintosh: Overview by Apple Computer, Inc. Addison-Wesley. on Page 52 there is some discussion of the STR# resource format and the routine GetIndString. Inside Macintosh: Text by Apple Computer, Inc. Addison-Wesley. on Page 5-50 GetIndString function is described, page 5-9 includes some discussion of the string list format. Inside Macintosh: Memory by Apple Computer, Inc. Addison-Wesley. A discussion of memory managment, handles, what they are, and how to use them. The C Programming Language 2nd edition by Brian W. Kernighan and Dennis M. Ritchie. Prentice Hall. Comments for the routines provided herein have been included in the file strlist.h. Also, there is a 411 help file. SERVICES PROVIDED (OVERVIEW) - routines for creating string lists in memory or retrieving them from resource files. - routines for querying information stored in string lists including their size, and in-place access to strings in the list. - routines for creating mapped index vectors containing pointers to strings stored in string lists. string list maps provide quick access to strings stored in string lists. both sorted maps and unsorted maps can be created. - a complete set of operations for adding, deleting, and inserting, strings into string lists, including routines for adding strings to alphabetically sorted string lists and facilities for searching string lists. - routines for building menus from string lists, and routines for filling list manager lists using strings stored in string lists. - routines for treating string lists as 'sets' of strings providing the traditional AND, OR, and XOR set operations, as well as subset and equivalence tests. BE CAREFUL (CAVEATS) I think these routines are safe to use, but you should do your own testing. I have provided the source code, and if you find any bugs, please let me know right away so I can provide corrections in future versions. I advertise a finder's fee of $10.00 cash for errors in any of my products. COMPARISONS AND ORDERING All string comparisons are done using the OSUtilities function RelString. the compile time variable SLUSECASE determines if the comparison will be case sensitive or non case sensitive. by default, SLUSECASE is defined as false. you can override this by predefining the compile time variable before compiling strlist.c All of the routines that treat string lists as sets of strings expect that the string lists passed to them will be alphabetically sorted. OVERVIEW OF ROUTINES creating your own string lists: Handle NewStringList(void); Handle MakeStringList(long n, ...); retrieving string lists stored in resource files: Handle GetStringList(short id); Handle Get1StringList(short id); accessing information in string lists: short StringListSize(Handle list); StringPtr StringListElt(Handle list, short elt); /* O(n) */ StringPtr RetrieveIndString(Handle list, short elt, StringPtr the_string); recovering memory occupied by string lists: void DisposeStringList(Handle list); speedy access routines for information in string lists via a map: StringPtr** MakeStringListMap(Handle list); StringPtr MapStringListElt(StringPtr** string_map, short elt);/*O(k)*/ WithStringList(stringlist, map) /* MACRO */ speedy access routines for information in string lists via sorted map: StringPtr** MakeSortedStringListMap(Handle list); WithSortedStringList(stringlist, map) /* MACRO */ deleting elments from a string list: void StringListRemove(Handle list, short elt); void ClearStringList(Handle list); adding elements to a string list (unsorted): void StringListInstall(Handle list, short elt, StringPtr s); void StringListAppend(Handle list, StringPtr s); void StringListPrepend(Handle list, StringPtr s); adding elements to a string list (sorted): short StringListInsert(Handle list, StringPtr s); short StringListRInsert(Handle list, StringPtr s); finding elements in a string list (test for membership in sets): short FindStringList(Handle list, StringPtr s); creating menus using strings stored in a string list: MenuHandle StringListToMenu(Handle list, short id, StringPtr name); filling list manager lists using strings stored in a string list: void StringListToList(Handle list, ListHandle the_list); using string lists as sets of strings: Handle StringListUnion(Handle A, Handle B); /* A | B */ Handle StringListIntersection(Handle A, Handle B); /* A & B */ Handle StringListDifference(Handle A, Handle B); /* A ^ B */ Boolean StringListSubset(Handle A, Handle B); /* A contains B */ Boolean StringListEquivalent(Handle A, Handle B); /* A == B */ SPECIFIC ROUTINE DESCRIPTIONS NewStringList formal declaration: Handle NewStringList(void); arguments: none return value: A Handle containing a empty string list. if an error occurs, NULL is returned. description: NewStringList creates a new string list handle in the current heap zone. The string list created contains no strings, and the count value is set to zero. example application: In this example, we create a new, empty string list: { Handle my_string_list; my_string_list = NewStringList(); ... notes: you can call DisposeHandle to dispose of a string list created by NewStringList. MakeStringList formal declaration: Handle MakeStringList(long n, ...); arguments: n = the number of c style strings that follow in the ... parameter list ... = n c style strings return value: A Handle to a string list containing the strings specified in the ... parameter list in the same order as they were provided as parameters. if an error occurs, NULL is returned. description: MakeStringList creates a new string list handle in the current heap zone containing the strings provided as parameters. the number of strings provided as parameters must match the number of specified in the value n. if an error occurs, NULL is returned. example application: in this example we create a string list containing 5 elements: { Handle my_string_list; my_string_list = MakeStringList(5, "this", "is", "a", "string", "list"); ... notes: you can call DisposeHandle to dispose of a string list created by MakeStringList. GetStringList formal declaration: Handle GetStringList(short id); arguments: id = the resource id of the STR# resource containing the string list return value: A Handle to a string list resource or NULL if an error occurs. description: GetStringList is equivalent to GetResource('STR#', id). example application: in this example, we retrieve the string list with id 128: { Handle my_string_list; my_string_list = GetStringList(128); ... notes: you should not call DisposeHandle to dispose of a string list retrieved by GetStringList as such string lists are registed in the resource file. Instead, after you are done with the string list call ReleaseResource(). You can call DisposeStringList on a string list created by GetStringList. Get1StringList formal declaration: Handle Get1StringList(short id); arguments: id = the resource id of the STR# resource containing the string list return value: A Handle to a string list resource or NULL if an error occurs. description: Get1StringList is equivalent to Get1Resource('STR#', id) and hence it only searches the current resource file for string list resources. example application: in this example, we retrieve the string list with id 128 searching only the current resource file: { Handle my_string_list; my_string_list = GetStringList(128); ... notes: you should not call DisposeHandle to dispose of a string list retrieved by Get1StringList as such string lists are registed in the resource file. Instead, after you are done with the string list call ReleaseResource(). You can call DisposeStringList on a string list created by GetStringList. DisposeStringList formal declaration: void DisposeStringList(Handle list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: none. description: DisposeStringList recovers the memory occupied by a string list. After determining if the handle refers to a resource by checking the handle's flag values, DisposeStringList either calls ReleaseResource for resource handles or calls DisposeHandle for regular handles. example application: Here, we a get a string list from a resource file, and and do away with it, then we create a new string list and do away with it as well. Note: DisposeStringList does the right thing in both cases calling ReleaseResource for the resource handle and calling DisposeHandle for the list we allocated in memory ourselves. { Handle my_string_list; my_string_list = GetStringList(128); if (my_string_list != NULL) { ...some statements using the string list... DisposeStringList(my_string_list); } my_string_list = MakeStringList(5, "this", "is", "a", "string", "list"); if (my_string_list != NULL) { ...some statements using the string list... DisposeStringList(my_string_list); } ... notes: none. StringListSize formal declaration: short StringListSize(Handle list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: the number of strings contained in the string list parameter. description: StringListSize returns the value stored in the count field of the string list handle. the number returned corresponds to the number of strings stored in the list. example application: here we get a string list resource and calculate it's size. { Handle my_string_list; short number_of_strings; my_string_list = GetStringList(128); number_of_strings = StringListSize(my_string_list); ... notes: none. StringListElt formal declaration: StringPtr StringListElt(Handle list, short elt); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. elt = the index of the string list element. remember, elements in string lists are indexed 1, 2, 3, ..., n. return value: a pointer to the requested string list element or NULL if elt. description: StringListElt returns a pointer to a specific element in the string list handle. The pointer returned refers directly to the data inside of the string list handle. example application: Here, we draw every element in a string list. Note the calls to HLock and HUnlock surrounding the part where we access the strings. { Handle my_string_list; short number_of_strings, index; StringPtr a_string; my_string_list = GetStringList(128); number_of_strings = StringListSize(my_string_list); HLock(my_string_list); /* lock the handle so it does not move */ for (index = 1; index <= number_of_strings; index++) { a_string = StringListElt(my_string_list, index); MoveTo(10, index*20); DrawString(a_string); } HUnlock(my_string_list); ... notes: StringListElt returns a pointer that refers to data stored inside of the string list handle. Some toolbox calls can cause handles to move in memory and invalidate this pointer unless the string list handle is locked. Also, the pointer returned may not always be alligned at an even address. Each call to StringListElt involves a linear search of the string list for the element requested. If you are frequently accessing strings stored in a string list and you are noticing a performance dropoff because of this, then you should call MakeStringListMap and access the strings directly using the MapStringListElt routine (StringListElt is uses O(n) time per lookup while MapStringListElt uses O(k) time per lookup). For example, the example application in StringListElt requires O(n*n) time while the example application of MakeStringListMap only requires O(n) time for the same task, and MakeSortedStringListMap only requires O(nlogn) time. RetrieveIndString formal declaration: StringPtr RetrieveIndString(Handle list, short elt, StringPtr the_string); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. elt = the index of the string list element. remember, elements in string lists are indexed 1, 2, 3, ..., n. the_string = a pointer to a variable of type Str255 to copy the string into. return value: the_string, or NULL if the elt was out of bounds. description: RetrieveIndString copies the indicated string list element from the string list into the string pointed to by the_string. RetrieveIndString returns the value passed in the third parameter, or NULL if the index was out of bounds. example application: here, we copy element 4 from the string list into the string variable my_string: { Handle my_string_list; Str255 my_string; my_string_list = GetStringList(128); RetrieveIndString(my_string_list, 4, my_string); ... notes: you do not have to lock the string list when using this call to retrieve string list elements. MakeStringListMap formal declaration: StringPtr** MakeStringListMap(Handle list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: a handle to an array of string pointers. description: MakeStringListMap creates an array of string pointers referring to consecutive string list elements. The string list is locked high in the heap before the mapping array is created. A map created in this way can be used to directly access string list elements using the function MapStringListElt without the linear search overhead required by StringListElt. example application: in this example, we use a string list map to consecutively draw string list elements on the screen. { Handle my_string_list; StringPtr** the_map, the_string; short number_of_strings, i; my_string_list = NewStringList(); ...several hundred strings are added here... the_map = MakeStringListMap(my_string_list); if (the_map != NULL) { number_of_strings = StringListSize(my_string_list); for (i=1; i <= number_of_strings; i++) { the_string = MapStringListElt(the_map, i); MoveTo(10, i*10); DrawString(the_string); } HUnlock(my_string_list); DisposeHandle((Handle) the_map); } ... notes: a map created by MakeStringListMap can be disposed of with a call to DisposeHandle((Handle) the_map). Since MakeStringListMap locks the string list handle, you should remember to unlock the handle once you dispose of the map. also note: do not unlock the string list handle until you are completely done with the map--unlocking the string list will invalidate pointers stored in the map. MakeSortedStringListMap formal declaration: StringPtr** MakeSortedStringListMap(Handle list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: a handle to an array of string pointers with the pointers sorted so that the map refers to the strings in the string list in alphabetical order. if SLUSECASE is true, case sensitive ordering is used. description: MakeSortedStringListMap is identical to MakeStringListMap except that the pointers in the map are sorted so that they refer to the string in the string list in aphabetical order. example application: in this example, we use a string list map to consecutively draw string list elements on the screen in alphabetical order. { Handle my_string_list; StringPtr** the_map, the_string; short number_of_strings, i; my_string_list = NewStringList(); ...several hundred strings are added here... the_map = MakeSortedStringListMap(my_string_list); if (the_map != NULL) { number_of_strings = StringListSize(my_string_list); for (i=1; i <= number_of_strings; i++) { the_string = MapStringListElt(the_map, i); MoveTo(10, i*10); DrawString(the_string); } HUnlock(my_string_list); DisposeHandle((Handle) the_map); } ... notes: a map created by MakeSortedStringListMap can be disposed of with a call to DisposeHandle((Handle) the_map). Since MakeSortedStringListMap locks the string list handle, you should remember to unlock the handle once you dispose of the map. also note: do not unlock the string list handle until you are completely done with the map--unlocking the string list will invalidate pointers stored in the map. MapStringListElt formal declaration: StringPtr MapStringListElt(StringPtr** string_map, short elt); arguments: string_map = a string list map created by MakeStringListMap. elt = the index of the string list element. remember, elements in string lists are indexed 1, 2, 3, ..., n. return value: a pointer to the string in the string list. description: MapStringListElt uses the string list map to look up the address of the requested string in the string list. example application: see MakeStringListMap notes: none. WithStringList MACRO formal declaration: #define WithStringList(stringlist, map) arguments: stringlist = an value of type string list. map = a variable of type StringPtr** for use in the macro. you do not need to initialize this variable, all you do is declare it. return value: not applicable. description: WithStringList creates a map for the string list that will be available for use in the statement immediately following the macro invocation. In addition, the macro disposes of the map and unlocks the list once the statement has completed execution. It is usually most convienient to follow the macro with a compound statement. example application: here, we use the WithStringList macro to create a map then we use the map to display the strings on the screen. { Handle my_string_list; StringPtr** the_map; short number_of_strings, index; my_string_list = MakeStringList(4, "red", "green", "orange", "blue"); WithStringList(my_string_list, the_map) { number_of_strings = StringListSize(my_string_list); for (i=1; i <= number_of_strings; i++) { MoveTo(10, i*10); DrawString(MapStringListElt(the_map, i)); } } ... notes: macro parameters may be evaluated more than once in the macro output so it's best to use variables here as in the above example. WithSortedStringList MACRO formal declaration: #define WithSortedStringList(stringlist, map) arguments: stringlist = an value of type string list. map = a variable of type StringPtr** for use in the macro. you do not need to initialize this variable, all you do is declare it. return value: not applicable. description: WithSortedStringList creates a map for the string list that will be available for use in the statement immediately following the macro invocation. the pointers in the list are sorted so that the map refers to the strings in the list in alphabetical order. if SLUSECASE is true, case sensitive comparisons are used in ordering the map pointers. In addition, the macro disposes of the map and unlocks the list once the statement has completed execution. It is usually more convienient to follow the macro with a compound statement. example application: Here, we use the WithSortedStringList macro to create a list of strings, and then we use the map to display those strings on the screen in alphabetical order. { Handle my_string_list; StringPtr** the_map; short number_of_strings, index; my_string_list = MakeStringList(4, "red", "green", "orange", "blue"); WithSortedStringList(my_string_list, the_map) { number_of_strings = StringListSize(my_string_list); for (i=1; i <= number_of_strings; i++) { MoveTo(10, i*10); DrawString(MapStringListElt(the_map, i)); } } ... notes: macro parameters may be evaluated more than once in the macro output so it's best to use variables here as in the above example. StringListRemove formal declaration: void StringListRemove(Handle list, short elt); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. elt = the index of the string list element. remember, elements in string lists are indexed 1, 2, 3, ..., n. return value: none. description: StringListRemove deletes the specified element from the string list updating the count field appropriately. example application: here, we remove element 4 from a string list. { Handle my_string_list; my_string_list = MakeStringList(4, "red", "green", "orange", "blue"); StringListRemove(my_string_list, 3); /* remove the word "orange" */ ... notes: none. ClearStringList formal declaration: void ClearStringList(Handle list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: none. description: ClearStringList removes all of the strings from the string list making it an empty list. example application: here, we clear the string list so it contains no elements. { Handle my_string_list; my_string_list = MakeStringList(4, "red", "green", "orange", "blue"); ClearStringList(my_string_list); ... notes: none. StringListInstall formal declaration: void StringListInstall(Handle list, short elt, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. elt = the index where the string list element will be placed. remember, elements in string lists are indexed 1, 2, 3, ..., n. s = a pointer to the string to add to the list return value: none. description: StringListInstall installs a string into the string list at the indicated element position. example application: Here, we insert a string into the list at position 2. { Handle my_string_list; my_string_list = MakeStringList(3, "the", "brown", "fox"); /* my_string_list = ("the", "brown", "fox") */ StringListInstall(my_string_list, 2, "\pquick"); /* my_string_list = ("the", "quick", "brown", "fox") */ ... notes: none. StringListAppend formal declaration: void StringListAppend(Handle list, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. s = a pointer to the string to add to the list return value: none. description: StringListAppend adds the string s to the end of the string list as the last element in the list. example application: here, we add an element to the end of a string list. { Handle my_string_list; my_string_list = MakeStringList(3, "my", "list", "of"); /* my_string_list = ("my", "list", "of") */ StringListAppend(my_string_list, "\pstrings"); /* my_string_list = ("my", "list", "of", "strings") */ ... notes: none. StringListPrepend formal declaration: void StringListPrepend(Handle list, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. s = a pointer to the string to add to the list return value: none. description: StringListPrepend adds the string s to the string list placing it in the first element position. example application: here, we add an element to the front of the string list. { Handle my_string_list; my_string_list = MakeStringList(3, "heap", "of", "strings"); /* my_string_list = ("heap", "of", "strings") */ StringListPrepend(my_string_list, "\pA big"); /* my_string_list = ("A big", "heap", "of", "strings") */ ... notes: none. StringListInsert formal declaration: short StringListInsert(Handle list, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. s = a pointer to the string to add to the list return value: the position in the list of strings where the string was installed, or zero if an error occurs. description: StringListInsert adds the string to a string list that is sorted in ascending, non case sensitive, alphabetical order in such a way that the list remains sorted after the string has been added. example application: in this example we insert the string delta into an alphabetically sorted string list. { Handle my_string_list; my_string_list = MakeStringList(3, "alpha", "beta", "gamma"); /* my_string_list = ("alpha", "beta", "gamma") */ StringListInsert(my_string_list, "\pdelta"); /* my_string_list = ("alpha", "beta", "delta", "gamma") */ ... notes: none. StringListRInsert formal declaration: short StringListRInsert(Handle list, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. s = a pointer to the string to add to the list return value: the position in the list of strings where the string was installed, or zero if an error occurs. description: StringListRInsert adds the string to a string list that is sorted in descending, non case sensitive, alphabetical order in such a way that the list remains sorted after the string has been added. example application: in this example we insert the string delta into an alphabetically sorted string list. The list is sorted in descending order. { Handle my_string_list; my_string_list = MakeStringList(3, "gamma", "beta", "alpha"); /* my_string_list = ("gamma", "beta", "alpha") */ StringListRInsert(my_string_list, "\pdelta"); /* my_string_list = ("gamma", "delta", "beta", "alpha") */ ... notes: none. FindStringList formal declaration: short FindStringList(Handle list, StringPtr s); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. s = a pointer to the string to find in the list return value: the position in the list of strings where the string was found or zero if the string is not in the list. description: FindStringList searches the list of strings in sequential order until it finds a non case sensitive match for the string. If a match is the index is returned, otherwise, if there is no match, FindStringList returns zero. example application: Here, we use the FindStringList routine to find the index of the indicated string. { Handle my_string_list; short position; my_string_list = MakeStringList(5, "the", "word", "is", "hidden", "here"); position = FindStringList(my_string_list, "\phidden"); if (position != 0) { /* position == 4 */ } position = FindStringList(my_string_list, "\pUnused"); /* position == 0, 'unused' is not in the list */ ... notes: none. StringListToMenu formal declaration: MenuHandle StringListToMenu(Handle list, short id, StringPtr name); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. id = the menu id for the menu name = the menu title, NULL is OK. return value: the created menu handle. description: StringListToMenu creates a new menu handle filling in the menu items using the strings in the string list. items in the string list will correspond to items in the menu on a one to one basis. i.e. string list element one will be the same as menu item one, and so on, and so on.... example application: Here, we create a menu for use with the PopUpMenuSelect function.. { Handle my_string_list; MenuHandle my_menu; long result; short item; my_string_list = MakeStringList(3, "Red", "Green", "Blue"); my_menu = StringListToMenu(my_string_list, 128, "\pColours"); InsertMenu(my_menu, -1); result = PopUpMenuSelect(my_menu, 100, 100, 1); DeleteMenu(128); if (HiWord(result) != 0) { item = LoWord(result); ..... } ... notes: by default, StringListToMenu calls SetItem to add the strings into the menu handle and as such the set of special menu formatting characters are not interpreted by the menu manager. If you would like to have the menu formatting characters interpreted when string list elements are added to menus then you can define the compile time variable INTERPRETMENUCHARS in the file "strlist.h". StringListToList formal declaration: void StringListToList(Handle list, ListHandle the_list); arguments: list = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. the_list = a list handle return value: none. description: StringListToList fills in the first column of the ListHandle so it contains all of the strings from the string list. example application: here, we copy a string list into a list manager list. { Handle my_string_list; ListHandle my_list_manager_list; WindowPtr the_window; Rect bounds, dataBounds; Point cSize; /* set up some stuff */ SetPt(&cSize, 0, 0); SetRect(&dataBounds, 0, 0, 1, 0); SetRect(&bounds, 100, 100, 200, 200); /* make a window */ the_window = NewWindow(NULL, &bounds, "\pstrlist", true, noGrowDocProc, (WindowPtr) (-1), false, 0); SetPort(the_window); /* make a list */ OffsetRect(&bounds, -bounds.left, -bounds.top); my_list_manager_list = LNew(&bounds, &dataBounds, cSize, 0, the_window, true, false, false, true); /* make a string list */ my_string_list = MakeStringList(3, "Red", "Green", "Blue"); /* put the string list into the list */ StringListToList(my_string_list, my_list_manager_list); ... notes: recall string lists elements are indexed elt = 1, 2, ..., n while elements contained in ListHandles created by StringListToList are indexed cell.v = 0, 1, 2, ..., n-1. StringListUnion formal declaration: Handle StringListUnion(Handle A, Handle B); arguments: A = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. B = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: a string list handle. description: StringListUnion returns a new string list handle containing all of the strings that appear in both string list A and string list B, or NULL if an error occurs. if SLUSECASE is true, case sensitive comparisons are used. operation = OR example application: here, we calculate the union of two sets of strings. { Handle A, B, C; A = MakeStringList(4, "red", "green", "orange", "blue"); B = MakeStringList(4, "yellow", "green", "purple", "blue"); C = StringListUnion(A, B); /* C now contains: {"blue", "green", "orange", "purple", "red", "yellow"} */ ... notes: in the present implementation, the result will be alphabetically sorted. StringListIntersection formal declaration: Handle StringListIntersection(Handle A, Handle B); arguments: A = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. B = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: a string list handle. description: StringListIntersection returns a new string list handle containing only those strings that appear in both string list A and string list B, or NULL if an error occurs. if SLUSECASE is true, case sensitive comparisons are used. operation = AND example application: here, we calculate the intersection of two sets of strings. { Handle A, B, C; A = MakeStringList(4, "red", "green", "orange", "blue"); B = MakeStringList(4, "yellow", "green", "purple", "blue"); C = StringListIntersection(A, B); /* C now contains: {"blue", "green"} */ ... notes: in the present implementation, the result will be alphabetically sorted. StringListDifference formal declaration: Handle StringListDifference(Handle A, Handle B); arguments: A = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. B = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: a string list handle. description: StringListDifference returns a new string list handle containing all the strings that do not appear in both A and B. if SLUSECASE is true, case sensitive comparisons are used. operation = XOR example application: here, we calculate the difference of two sets of strings. { Handle A, B, C; A = MakeStringList(4, "red", "green", "orange", "blue"); B = MakeStringList(4, "yellow", "green", "purple", "blue"); C = StringListDifference(A, B); /* C now contains: {"orange", "purple", "red", "yellow"} */ ... notes: in the present implementation, the result will be alphabetically sorted. StringListSubset formal declaration: Boolean StringListSubset(Handle A, Handle B); arguments: A = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. B = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: true or false. description: StringListSubset returns true if the strings contained in B make up a subset of the strings contained in A. if SLUSECASE is true, case sensitive comparisons are used. example application: here, we call StringListSubset to determine if B is a subset of A. { Handle A, B, C; A = MakeStringList(4, "red", "green", "orange", "blue"); B = MakeStringList(4, "red", "orange", "blue"); if (StringListSubset(A, B)) { /* B is infact a subset of A */ } ... notes: none. StringListEquivalent formal declaration: Boolean StringListEquivalent(Handle A, Handle B); arguments: A = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. B = a handle to a string list created by NewStringList, MakeStringList, GetStringList, or Get1StringList. return value: true or false. description: StringListEquivalent returns true if the strings both string lists contain the same strings. if SLUSECASE is true, case sensitive comparisons are used. example application: here, we call StringListEquivalent to if the two sets are the same. { Handle A, B; A = MakeStringList(4, "red", "green", "orange", "blue"); B = MakeStringList(4, "red", "green", "orange", "blue"); if (StringListEquivalent(A, B)) { /* yes, the are the same sets */ } ... notes: none. file strlist.txt Copyright (C) 1995, 1996 by John Montbriand. All Rights Reserved. end of file